package com.powernode.anno;

import com.alibaba.fastjson.JSON;
import com.powernode.domain.SysLog;
import com.powernode.domain.SysUser;
import com.powernode.service.SysLogService;
import com.powernode.service.SysUserService;
import com.powernode.threadpool.LogThreadPool;
import com.powernode.utils.PowerAuthMenuUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Date;

/**
 * 通过切面获得到有此注解的方法的一些信息 保存到日志数据库中
 */
@Aspect
@Component
public class LogAspect {

    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysLogService sysLogService;

    /**
     * username 用户名
     * operation 操作
     * method 方法全限定名
     * params 参数
     * time 执行时间
     * ip ip地址
     * create_date  创建时间
     *
     * @param joinPoint
     * @param logAnnotation
     * @return
     */
    @Around("@annotation(logAnnotation)")
    public Object logAspect(ProceedingJoinPoint joinPoint, LogAnnotation logAnnotation) {
        //获取userId
        Long sysUserId = PowerAuthMenuUtil.getSysUserId();
        SysUser sysUser = sysUserService.getById(sysUserId);
        //获取操作
        String operate = logAnnotation.operate();

        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        String name = methodSignature.getName();
        //获取类字节码对象
        Class<?> cls = joinPoint.getTarget().getClass();
        //目标类型
        String clsName = cls.getName();

        //请求参数
        Object[] args = joinPoint.getArgs();
        String object = JSON.parseObject(Arrays.toString(args), String.class);
        //方法名
        String methodName = clsName + "." + name + "()";
        //执行时间
        long start = System.currentTimeMillis();
        Object proceed = null;
        try {
            proceed = joinPoint.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        long end = System.currentTimeMillis();
        long time = end - start;
        //获取ip
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        //request.getRemoteAddr();  //返回192.168.2.10
        String ip = request.getRemoteHost(); //返回192.168.2.10
        //创建对象 并赋值
        SysLog sysLog = SysLog.builder()
                .username(sysUser.getUsername())
                .operation(operate)
                .method(methodName)
                .params(object)
                .time(time)
                .ip(ip)
                .createDate(new Date())
                .build();
        //插入到数据库
        //使用线程池进行插入
//        sysLogService.save(sysLog);
        LogThreadPool.executor().execute(()->sysLogService.save(sysLog));
        return proceed;
    }
}
